﻿using AuSys.Repos.Identities;
using AuSys.Repos.Identities.Abstractions;
using AuSys.Services.App.ActionFilters;
using AuSys.Services.App.Authentication;
using AuSys.Services.App.ConfigReader.Abstractions;
using AuSys.Services.App.Cors;
using AuSys.Services.App.FileStorage;
using AuSys.Services.App.Mapping;
using AuSys.Services.App.OpenApi;
using AuSys.Services.App.UserInfo;
using AuSys.Services.App.UserInfo.Abstractions;
using AuSys.Services.App.Validation;
using AuSys.Utils.DependencyInjection;
using AuSys.Utils.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace AuSys.Services.App
{
    public static class AddToServices
    {
        public static IServiceCollection AddAppServices(
            this IServiceCollection services, IConfiguration config)
        {
            services.AddCors(config);
            services.AddJwtService(config);

            //将全部的ConfigReader注册为singleton服务
            var configReaders = TypeSearcher.Search<IConfigReader>();
            configReaders.ForEach(f => services.AddSingleton(f));
            //将全部的Filter注册为Scoped服务
            var filters = TypeSearcher.Search<IFilterMetadata>();
            filters.ForEach(f => services.AddScoped(f));
            services.AddControllers(options =>
            {
                options.Filters.Add<ApiExceptionFilter>();
                options.Filters.Add<UserAccessScopeFilter>();
            }).AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
            });
            services.Configure<ApiBehaviorOptions>(opt =>
            {
                opt.SuppressModelStateInvalidFilter = true;
            });

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddScoped<IBasicUserInfoProvider, UserRepo>();
            services.AddScoped<IBasicUserRepo, UserRepo>();
            services.AddScoped<IUserIdProvider, HttpUserIdProvider>();
            services.AddScoped<IUserInfoService, HttpUserInfoService>();
            services.AddScoped<LazyInject<IUserInfoService>>();

            services.AddNSwagDocument();
            services.AddSingleton<NSwagTsGenService>();

            services.SetupAutoMapper();
            services.SetupFluentValidation();

            services.SetupFileStorage(config);
            return services;
        }
    }
}
